from itertools import groupby as it
from ib.ext.EClientSocket import EClientSocket
from ib.ext.Contract import Contract
from ib.ext.EWrapper import EWrapper
from wrapperfactory import WrapperType

from time import sleep, strftime
import config as cfg
from random import randint

import pdb

#------------------------------------------------------------------
#             MktInfo()
#------------------------------------------------------------------
class MktInfo:
     def __init__(self, lst):
          l = [str(i) for i in lst]
          self._data =  dict([str(i).split() for i in l])
          #any of the PriceMsg contains tickerId. Get it from first
          self._data['tickerId'] = lst[0].tickerId
                    
     def __str__(self):
          contract = cfg.contractmap[self._data['tickerId']]
          self._data['symb'] = contract.m_symbol
          self._data['type'] = contract.m_secType
          d = self._data
          exclude = ['tickerId', 'last']
          return str(
              [str(d[k]) for k in d.keys() if k not in exclude])
          
#     def __del__(self):
#         cfg.msgq.queue.clear()
#         del cfg.contractmap[self._data['tickerId']]



Wrapper = WrapperType('Wrapper',(EWrapper,),cfg.callbacklist)

class IBsession:
    def __init__(self, host='localhost', port=7496, clientId=0):
        self.host = host
        self.port = port
        self.clientId = clientId
        self.wrapper = Wrapper()
        self.connection = EClientSocket(self.wrapper)
        self.connection.eConnect(self.host, self.port, self.clientId)

#    def eConnect(self):
        
    def reqAccountUpdates(self):
        self.connection.reqAccountUpdates(1, '')

    def reqOpenOrders(self):
        self.connection.reqOpenOrders()

    def reqExecutions(self):
        filt = ExecutionFilter()
        self.connection.reqExecutions(filt)

    def reqIds(self):
        self.connection.reqIds(10)

    def reqNewsBulletins(self):
        self.connection.reqNewsBulletins(1)

    def cancelNewsBulletins(self):
        self.connection.cancelNewsBulletins()

    def setServerLogLevel(self):
        self.connection.setServerLogLevel(3)

    def reqAutoOpenOrders(self):
        self.connection.reqAutoOpenOrders(1)

    def reqAllOpenOrders(self):
        self.connection.reqAllOpenOrders()

    def reqManagedAccts(self):
        self.connection.reqManagedAccts()

    def requestFA(self):
        self.connection.requestFA(1)

# return bid/ask from memory mktdb

    def reqSnapshotMktData(self, contract):
        """ trigers tickPrice,tickPrice(),tickSize()
        tickOptionComputation(),tickGeneric(),tickString()
        tickEFP(),tickSnapshotEnd()
        """
        r = randint(1,10000)
        while cfg.contractmap.has_key(r):
            r = randint(1,10000)
        
        cfg.contractmap[r] = contract
        self.connection.reqMktData(r, contract,'', True)
        
        # REFACTOR sleep for notify when queue is ready
        sleep(3)
        l = list(cfg.msgq.queue.__iter__())
        if (cfg.debug):
            cfg.msglog = l
        #filter in price envents
        price_msg = [t for t in  l if (t[0][1]=='tickPrice'
                                         and t[1][1] == r )]
        price_tuple = [t[1:4] for t in price_msg]

        vol_tuple = [t for t in  l if (t[0][1]=='optionCalc'
                                         and t[1][1] == r )]
        #if (len(vol_tuple) > 0):
            #quoteinfo['ivol'] = vol_tuple['ivol']

        # insert into sql
        #TODO: a separate thread should be taking care of
        #      going to queu un updating necessary db
        cur = cfg.dbcon.cursor()
        for tt in price_tuple:
             k,v = zip(*tt)
             cur.execute('insert into prix values(?,?,?)',v) 

             res = cur.execute("""select price from prix
                              where field = '%s'
                              or field = '%s'""" %('bid','ask'))

        return res.fetchall()

        #fg = it.groupby(price_tuple, lambda x:x[2][1])
        #tbid = [t for t in fg if fg.next()[0] == bid]
        

   
    def reqHistoricalData(self):
        contract = Contract()
        contract.m_symbol = 'QQQQ'
        contract.m_secType = 'STK'
        contract.m_exchange = 'SMART'
        endtime = strftime('%Y%m%d %H:%M:%S')
        self.connection.reqHistoricalData(
            tickerId=1,
            contract=contract,
            endDateTime=endtime,
            durationStr='1 D',
            barSizeSetting='1 min',
            whatToShow='TRADES',
            useRTH=0,
            formatDate=1)

    def eDisconnect(self):
        sleep(5)
        self.connection.eDisconnect()
